package com.ruoyi.fjtseac.service

import com.baomidou.mybatisplus.core.conditions.Wrapper
import com.ruoyi.common.constant.HttpStatus
import com.ruoyi.common.core.domain.AjaxResult
import com.ruoyi.common.core.redis.RedisCache
import com.ruoyi.fjtseac.domain.dto.UpdateVideoForm
import com.ruoyi.fjtseac.domain.dto.VideoDto
import com.ruoyi.fjtseac.domain.po.Video
import com.ruoyi.fjtseac.mapper.VideoMapper
import com.ruoyi.fjtseac.service.impl.VideoServiceImpl
import com.ruoyi.fjtseac.util.COSUtil
import com.ruoyi.fjtseac.util.Constants
import com.ruoyi.fjtseac.util.FileUtil
import com.ruoyi.fjtseac.util.LocalFile
import org.springframework.mock.web.MockMultipartFile
import org.springframework.web.multipart.MultipartFile
import spock.lang.Specification
import spock.lang.Unroll

/**
 *
 * @author zzl
 * @date 2022/8/12 13:34
 */
class VideoServiceTest extends Specification {


    def fileUtil = Mock(FileUtil)
    def redisCache = Mock(RedisCache)
    def localFile = Mock(LocalFile)
    def videoMapper = Mock(VideoMapper)
    def videoServiceImpl = new VideoServiceImpl(fileUtil, localFile, videoMapper, redisCache)

    @Unroll
    def "upload(videoDto: #videoDto, videoUrl: #videoUrl, duration: #duration, String uuid), code: #httpStatus , msg: #resultMsg" () {
        given:
        localFile.getFileTime(videoDto.getVideoFile(), Constants.VIDEO) >> duration
        fileUtil.upload(videoDto.getVideoFile(), Constants.VIDEO, "uuid") >> videoUrl
        videoMapper.insert(_ as Video) >> num
        fileUtil.delete(_ as String[]) >> true

        when: "接口存在抛出异常的情况，而thrown()在接口正常不抛出异常会报错，故需要在正常时也抛出正常的异常"
        def response = videoServiceImpl.upload(videoDto, "uuid")


        then:
        with(response) {
            code == httpStatus
            msg == resultMsg
        }

        where:
        videoDto                                                              | videoUrl                         | duration | num || httpStatus         | resultMsg
        newVideoDto("天意", "C:\\Users\\zzl\\Desktop\\七叔-叶泽浩 - 客子光阴 七叔现场版.mp4", "http") | "http://cos.guangdong.cn/video1" | "05:10"  | 1   || HttpStatus.SUCCESS | "操作成功"
        newVideoDto("秦时明月", "D:\\45568f0582117caac65df45e03600d9d.jpeg", "http")      | Constants.FALSE                  | "06:10"  | 1   || HttpStatus.ERROR   | "视频文件因某种原因上传失败，请重新上传"
        newVideoDto("秦", "C:\\Users\\zzl\\Desktop\\七叔-叶泽浩 - 客子光阴 七叔现场版.mp4", "http")  | "http://cos.guangdong.cn/video2" | null     | 1   || HttpStatus.ERROR   | "获取视频时长失败"
        newVideoDto("视频", "C:\\Users\\zzl\\Desktop\\七叔-叶泽浩 - 客子光阴 七叔现场版.mp4", "http")  | "http://cos.guangdong.cn/video3" | "03:40"  | 0   || HttpStatus.ERROR   | "数据插入失败"

    }

    def newVideoDto(def title, def fileUrl, def cover) {
        return new VideoDto(videoTitle: title, videoFile: newMulFile(fileUrl), coverUrl: cover)
    }

    MultipartFile newMulFile(def fileUrl) {
        File file  = new File(fileUrl)
        FileInputStream input = new FileInputStream(file)
        MultipartFile multipartFile = new MockMultipartFile(file.getName(),file.getName(), "video/mpeg4", input)
        return multipartFile
    }

    @Unroll
    def "upload(file: #videoFile.getName(), String uuid), code: #httpStatus"()  {
        given:
        fileUtil.upload(videoFile, Constants.VIDEO, _ as String ) >> videoUrl

        when:
        def response = videoServiceImpl.upload(videoFile, _ as String)

        then:
        with(response) {
            code == httpStatus
        }

        where:
        videoUrl                         | videoFile                                                      || httpStatus
        "http://cos.guangdong.cn/video1" | newMulFile("C:\\Users\\zzl\\Desktop\\七叔-叶泽浩 - 客子光阴 七叔现场版.mp4") || HttpStatus.SUCCESS
        Constants.FALSE                  | newMulFile("D:\\45568f0582117caac65df45e03600d9d.jpeg")        || HttpStatus.ERROR
        Constants.FALSE                  | newMulFile("D:\\45568f0582117caac65df45e03600d9d.jpeg")        || HttpStatus.ERROR
    }

    @Unroll
    def "search(param: #param, pageNum: #pageNum, pageSize: #pageSize), code: #httpStatus"() {
        given: "输入条件：模拟videoMapper.selectList(_ as Wrapper<Video>)方法的返回值为 [video1, video2]的list"
        videoMapper.selectList(_ as Wrapper<Video>) >> resultSet

        when: "调用"
        def response = videoServiceImpl.search(param, pageNum, pageSize);

        then: "结果验证"
        with(response) {
            response.get("code") == httpStatus;
            response.get("data").getAt("total") == total;
        }
        where: "输入输出数据表格"
        param | pageNum | pageSize | resultSet                                                   || httpStatus         | pageCount | total
        null  | 1       | 10       | [new Video(videoTitle: "梦想"), new Video(videoTitle: "如梦令")] || HttpStatus.SUCCESS | 1         | 2
        "梦"   | 2       | 2        | [new Video(videoTitle: "梦想"), new Video(videoTitle: "如梦令")] || HttpStatus.SUCCESS | 1         | 2
        "1"   | 1       | 5        | []                                                          || HttpStatus.SUCCESS | 1         | 0
    }

    @Unroll
    def "delete(id: #id), msg: #resultMsg"() {
        given:
        videoMapper.selectById(id) >> video
        fileUtil.delete(_ as String[]) >> flag

        when:
        def response = videoServiceImpl.delete(id)

        then:
        with(response) {
            msg == resultMsg
        }

        where:
        id | video                 | flag  || resultMsg
        0  | null                  | true  || "该视频不存在"
        1  | new Video(videoId: 1, videoUrl: "http", coverUrl: "http") | false || "部分文件或全部文件删除文件失败，请登录服务器删除对应文件"
        2  | new Video(videoId: 2, videoUrl: "http", coverUrl: "http") | true || "操作成功"
    }

    @Unroll
    def "update(updateVideoForm: #updateVideoForm), code: #httpStatus" () {
        given:
        videoMapper.selectById(id) >> video
        videoMapper.updateById(_ as Video) >> num

        when:
        def response = videoServiceImpl.update(updateVideoForm)

        then:
        with(response) {
            msg == resultMsg
            code == httpStatus
        }

        where:
        id | updateVideoForm                                     | video                                                       | num || httpStatus         | resultMsg
        1  | new UpdateVideoForm(videoId: id, videoTitle: "修改后") | new Video(videoId: id, videoTitle: "修改前", coverUrl: "http") | 1   || HttpStatus.SUCCESS | "操作成功"
        -1 | new UpdateVideoForm(videoId: id, videoTitle: "修改后") | null                                                        | 0   || HttpStatus.ERROR   | "不存在该数据"
        2  | new UpdateVideoForm(videoId: id, videoTitle: "修改后") | new Video(videoId: id, videoTitle: "修改前", coverUrl: "http") | 0   || HttpStatus.ERROR   | "修改数据库视频记录失败"
    }



}
